package org.convallaria.infrastruct.rg.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.validation.annotation.Validated;

import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * 注册发现配置属性
 * 支持动态刷新和配置验证
 * 
 * @author gjh
 * @since 2025-01-27
 */
@Data
@RefreshScope
@Validated
@ConfigurationProperties(prefix = "convallaria.registry")
public class RegistryProperties {
    
    /**
     * 是否启用注册发现功能
     */
    private boolean enabled = true;
    
    /**
     * 服务发现配置
     */
    @NotNull
    private ServiceDiscovery serviceDiscovery = new ServiceDiscovery();
    
    /**
     * 健康检查配置
     */
    @NotNull
    private HealthCheck healthCheck = new HealthCheck();
    
    /**
     * 负载均衡配置
     */
    @NotNull
    private LoadBalancer loadBalancer = new LoadBalancer();
    
    /**
     * 监控配置
     */
    @NotNull
    private Monitoring monitoring = new Monitoring();
    
    /**
     * 服务发现配置
     */
    @Data
    public static class ServiceDiscovery {
        
        /**
         * 是否启用服务发现
         */
        private boolean enabled = true;
        
        /**
         * 服务发现超时时间
         */
        private Duration timeout = Duration.ofSeconds(5);
        
        /**
         * 服务发现重试次数
         */
        @Min(0)
        @Max(10)
        private int retryCount = 3;
        
        /**
         * 服务发现重试间隔
         */
        private Duration retryInterval = Duration.ofSeconds(1);
        
        /**
         * 是否启用服务订阅
         */
        private boolean enableSubscription = true;
        
        /**
         * 服务订阅超时时间
         */
        private Duration subscriptionTimeout = Duration.ofSeconds(10);
    }
    
    /**
     * 健康检查配置
     */
    @Data
    public static class HealthCheck {
        
        /**
         * 是否启用健康检查
         */
        private boolean enabled = true;
        
        /**
         * 健康检查间隔
         */
        private Duration interval = Duration.ofSeconds(30);
        
        /**
         * 健康检查超时时间
         */
        private Duration timeout = Duration.ofSeconds(5);
        
        /**
         * 健康检查重试次数
         */
        @Min(0)
        @Max(5)
        private int retryCount = 2;
        
        /**
         * 健康检查路径
         */
        @NotBlank
        private String path = "/actuator/health";
        
        /**
         * 存活检查路径
         */
        @NotBlank
        private String livenessPath = "/actuator/health/liveness";
        
        /**
         * 就绪检查路径
         */
        @NotBlank
        private String readinessPath = "/actuator/health/readiness";
        
        /**
         * 线程池大小
         */
        @Min(1)
        @Max(50)
        private int threadPoolSize = 10;
        
        /**
         * 是否启用异步健康检查
         */
        private boolean asyncEnabled = true;
    }
    
    /**
     * 负载均衡配置
     */
    @Data
    public static class LoadBalancer {
        
        /**
         * 是否启用负载均衡
         */
        private boolean enabled = true;
        
        /**
         * 默认负载均衡策略
         */
        @NotBlank
        private String defaultStrategy = "random";
        
        /**
         * 是否启用权重负载均衡
         */
        private boolean weightEnabled = true;
        
        /**
         * 是否启用版本优先
         */
        private boolean versionPreferred = true;
        
        /**
         * 是否启用区域优先
         */
        private boolean regionPreferred = true;
        
        /**
         * 最大重试次数
         */
        @Min(0)
        @Max(10)
        private int maxRetries = 3;
        
        /**
         * 重试间隔
         */
        private Duration retryInterval = Duration.ofMillis(100);
    }
    
    /**
     * 监控配置
     */
    @Data
    public static class Monitoring {
        
        /**
         * 是否启用监控
         */
        private boolean enabled = true;
        
        /**
         * 是否启用指标收集
         */
        private boolean metricsEnabled = true;
        
        /**
         * 指标收集间隔
         */
        private Duration metricsInterval = Duration.ofMinutes(1);
        
        /**
         * 是否启用审计日志
         */
        private boolean auditEnabled = true;
        
        /**
         * 审计日志级别
         */
        @NotBlank
        private String auditLevel = "INFO";
        
        /**
         * 是否启用性能监控
         */
        private boolean performanceEnabled = true;
        
        /**
         * 性能监控阈值（毫秒）
         */
        @Min(100)
        private long performanceThreshold = 1000;
        
        /**
         * 自定义标签
         */
        private Map<String, String> tags = new HashMap<>();
    }
}
